package com.mycompany.app.common.audit.access.filter;

import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken;
import org.acegisecurity.userdetails.UserDetails;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.filter.AbstractRequestLoggingFilter;

import com.mycompany.app.common.audit.access.filter.dao.ILoggingMessageDao;
import com.mycompany.app.common.audit.access.filter.model.LoggingMessage;
import com.mycompany.app.common.security.model.User;

/**
 * every reqest info like user name, ip, request date,request url are logged
 * into database after successful login.
 * 
 * @author Shawn.guo
 */
public class UserLoggingFilter extends AbstractRequestLoggingFilter {

    private ILoggingMessageDao logDao;

    @Override
    protected void initFilterBean() throws ServletException {

        this.setIncludeQueryString(true);
        this.setBeforeMessagePrefix("[");
        this.setBeforeMessageSuffix("]");
        super.initFilterBean();
    }

    @Override
    protected void afterRequest(HttpServletRequest request, String message) {

    }

    @Override
    protected void beforeRequest(HttpServletRequest request, String message) {

        String username;

        HttpSession session = request.getSession(false);
        if (session == null)
            return;
        // ignore annonymous user
        else if (SecurityContextHolder.getContext().getAuthentication() instanceof AnonymousAuthenticationToken) {
            return;
        } else {
            Object obj = SecurityContextHolder.getContext().getAuthentication()
                    .getPrincipal();
            if (obj instanceof UserDetails) {
                username = ((UserDetails) obj).getUsername();
               // check track flag
                if (!((User) obj).isTrackFlag()) {
                    if (logger.isDebugEnabled())
                        logger.debug(username + "[Track Flag]:"
                                + ((User) obj).isTrackFlag());
                    return;
                }
            } else {
                username = obj.toString();
            }
        }
        
        

        LoggingMessage logMessage = new LoggingMessage();
        logMessage.setUser(username);
        logMessage.setLogTime(new Date());
        logMessage.setRequestUrl(message);
        logMessage.setRemoteHost(request.getRemoteHost());
        logMessage.setRemoteIp(request.getRemoteAddr());
        logMessage.setUserAgent(request.getHeader("User-Agent"));
        logMessage.setOperation("N/A");

        if (logger.isDebugEnabled())
            logger.debug(logMessage.toString());

        if (logDao == null) {
            logDao = (ILoggingMessageDao) WebApplicationContextUtils
                    .getWebApplicationContext(this.getServletContext())
                    .getBean("loggingMessageDao");
        }
        logDao.save(logMessage);
    }

}
